﻿using System.Collections.Generic;

namespace Eric.SerialPorts
{
    public class BytePatternSearcher
    {
        private class PartialMatch
        {
            public int Index { get; private set; }
            public int MatchLength { get; set; }

            public PartialMatch(int index)
            {
                Index = index;
                MatchLength = 1;
            }
        }
        public static int IndexOf(List<byte> arrayToSearch, byte[] patternToFind)
        {
            return IndexOf(arrayToSearch.ToArray(), patternToFind);
        }

        public static int IndexOf(byte[] arrayToSearch, byte[] patternToFind)
        {
            if (patternToFind.Length == 0
              || arrayToSearch.Length == 0
              || arrayToSearch.Length < patternToFind.Length)
                return -1;

            var partialMatches = new List<PartialMatch>();

            for (int i = 0; i < arrayToSearch.Length; i++)
            {
                for (int j = partialMatches.Count - 1; j >= 0; j--)
                    if (arrayToSearch[i] == patternToFind[partialMatches[j].MatchLength])
                    {
                        partialMatches[j].MatchLength++;

                        if (partialMatches[j].MatchLength == patternToFind.Length)
                            return partialMatches[j].Index;
                    }
                    else
                        partialMatches.Remove(partialMatches[j]);

                if (arrayToSearch[i] == patternToFind[0])
                {
                    if (patternToFind.Length == 1)
                        return i;
                    partialMatches.Add(new PartialMatch(i));
                }
            }

            return -1;
        }
    }
}
